﻿using EFCore.BulkExtensions;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Yitter.IdGenerator;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 不良明细服务
    /// </summary>
    [Route("api/DeliveryQualityDetails")]
    [ApiDescriptionSettings("供应商模块", Name = "DeliveryQualityDetails", Order = 100)]

    public class DeliveryQualityDetailsService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WareDictData, MasterDbContextLocator> _wareDictDataRep; //仓库字典值仓储
        private readonly IRepository<SupplierInfo, MasterDbContextLocator> _supplierInfoRep; //供应商基本信息仓储
        private readonly IRepository<PurchaseOrder, MasterDbContextLocator> _purchaseOrderRep; //采购订单仓储
        private readonly IRepository<GoodsDelivery, MasterDbContextLocator> _goodsDeliveryRep; //送货单仓储
        private readonly IRepository<GoodsDeliveryDetails, MasterDbContextLocator> _goodsDeliveryDetailsRep; //送货单明细仓储
        private readonly IRepository<GoodsDeliveryAppointment, MasterDbContextLocator> _goodsDeliveryAppointmentRep; //送货单预约仓储
        private readonly IRepository<PurchaseOrderVsGoodsDelivery, MasterDbContextLocator> _purchaseOrderVsGoodsDeliveryRep; //采购订单与送货单关系仓储
        private readonly IRepository<CollectDeliveryDetails, MasterDbContextLocator> _collectDeliveryDetailsRep; //收货单明细仓储
        private readonly IRepository<SupplierExamineFlower, MasterDbContextLocator> _supplierExamineFlowerRep; //送货单审核记录仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="wareDictDataRep"></param>
        /// <param name="supplierInfoRep"></param>
        /// <param name="purchaseOrderRep"></param>
        /// <param name="goodsDeliveryRep"></param>
        /// <param name="goodsDeliveryDetailsRep"></param>
        /// <param name="goodsDeliveryAppointmentRep"></param>
        /// <param name="purchaseOrderVsGoodsDeliveryRep"></param>
        /// <param name="collectDeliveryDetailsRep"></param>
        /// <param name="supplierExamineFlowerRep"></param>
        public DeliveryQualityDetailsService(
            IRepository<WareDictData, MasterDbContextLocator> wareDictDataRep,
            IRepository<SupplierInfo, MasterDbContextLocator> supplierInfoRep,
            IRepository<PurchaseOrder, MasterDbContextLocator> purchaseOrderRep,
            IRepository<GoodsDelivery, MasterDbContextLocator> goodsDeliveryRep,
            IRepository<GoodsDeliveryDetails, MasterDbContextLocator> goodsDeliveryDetailsRep,
            IRepository<GoodsDeliveryAppointment, MasterDbContextLocator> goodsDeliveryAppointmentRep,
            IRepository<PurchaseOrderVsGoodsDelivery, MasterDbContextLocator> purchaseOrderVsGoodsDeliveryRep,
            IRepository<CollectDeliveryDetails, MasterDbContextLocator> collectDeliveryDetailsRep,
            IRepository<SupplierExamineFlower, MasterDbContextLocator> supplierExamineFlowerRep
        )
        {
            _wareDictDataRep = wareDictDataRep;
            _supplierInfoRep = supplierInfoRep;
            _purchaseOrderRep = purchaseOrderRep;
            _goodsDeliveryRep = goodsDeliveryRep;
            _goodsDeliveryDetailsRep = goodsDeliveryDetailsRep;
            _goodsDeliveryAppointmentRep = goodsDeliveryAppointmentRep;
            _purchaseOrderVsGoodsDeliveryRep = purchaseOrderVsGoodsDeliveryRep;
            _collectDeliveryDetailsRep = collectDeliveryDetailsRep;
            _supplierExamineFlowerRep = supplierExamineFlowerRep;
        }
        #endregion

        /// <summary>
        /// 分页查询不良明细信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("Page")]
        public async Task<PageResult<DeliveryQualityDetailsOutput>> Page([FromQuery] DeliveryQualityDetailsInput input)
        {
            var account = CurrentUserInfo.Account;

            var status = new List<int> { 2, 3, 6 };

            var list = await _collectDeliveryDetailsRep.DetachedEntities
                .Where(z => z.SupplierInfoCode == account)
                .Where(z => status.Contains((int)z.QualityResult))
                .Where(input.IsSupperHandle != YesOrNot.All, z => z.IsSupperHandle == input.IsSupperHandle)
                .Where(!string.IsNullOrEmpty(input.ProjectCode), u => EF.Functions.Like(u.ProjectCode, $"%{input.ProjectCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.DeliveryNo), u => EF.Functions.Like(u.CollectDelivery.DeliveryNo, $"%{input.DeliveryNo.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.SearchBeginTime), u => u.UpdatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                 u.UpdatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .OrderBy(PageInputOrder.OrderBuilder(input))
                .ProjectToType<DeliveryQualityDetailsOutput>()
                .ToADPagedListAsync(input.PageNo, input.PageSize);

            foreach (var item in list.Rows)
            {
                var goodsDelivery = await _goodsDeliveryRep.FirstOrDefaultAsync(z => z.DeliveryNo == item.CollectDelivery.DeliveryNo);

                item.PurchaseNo = goodsDelivery.PurchaseNo;
                item.PurchaseType = (await _wareDictDataRep.FirstOrDefaultAsync(z => z.Code == goodsDelivery.DeliveryType)).Value;
                item.DeliveryNo = goodsDelivery.DeliveryNo;
            }
            return list;
        }

        /// <summary>
        /// 创建质检后的送货单
        /// </summary>
        /// <returns></returns>
        [HttpPost("Add")]
        [UnitOfWork]
        public async Task Add([FromBody] List<AddDeliveryQualityInput> input)
        {
            if (input.Count == 0) throw Oops.Oh("详情不能为空");

            var supplierInfo = await _supplierInfoRep.FirstOrDefaultAsync(z => z.Code == CurrentUserInfo.Account);

            // 根据项目编号去重
            var projectDistinct = input.Select(z => z.ProjectCode).Distinct().ToList();
            foreach (var projectCode in projectDistinct)
            {
                var detailsList = input.Where(z => z.ProjectCode == projectCode).ToList();

                var detailsModel = input.Where(z => z.ProjectCode == projectCode).ToList().FirstOrDefault();

                // 查询采购单信息
                var purchaseOrderModel = await _purchaseOrderRep.FirstOrDefaultAsync(z => z.PurchaseNo == detailsModel.PurchaseNo && z.ProjectCode == projectCode);
                // 构建送货单
                var goodsDeliveryModel = new GoodsDelivery()
                {
                    PurchaseNo = detailsModel.PurchaseNo,
                    DeliveryNo = YitIdHelper.NextId().ToString(),
                    DeliveryType = purchaseOrderModel.PurchaseType,
                    Status = AuditStatusEnum.yuyuezhong,
                    SuppCode = supplierInfo.Code,
                    SuppName = supplierInfo.Name,
                    SuppPhone = supplierInfo.Tel,
                    SuppAddress = supplierInfo.ContactAddress,
                    ProjectCode = projectCode,
                    ReceName = "伟本智能（上海）股份有限公司",
                    ReceAddress = purchaseOrderModel.Address,
                    RecePhone = "021-57709082-8194或9183",
                    DeliveryQuantityTotal = detailsList.Sum(t => t.QualityNumber)
                };
                await _goodsDeliveryRep.InsertAsync(goodsDeliveryModel, true);

                var goodsDeliveryDetailsList = new List<GoodsDeliveryDetails>();
                // 遍历物料明细
                foreach (var details in detailsList)
                {
                    // 构建送货单明细
                    var goodsDeliveryDetails = details.Adapt<GoodsDeliveryDetails>();
                    goodsDeliveryDetails.GoodsDeliveryId = goodsDeliveryModel.Id;
                    goodsDeliveryDetails.ProjectCode = projectCode;
                    goodsDeliveryDetails.SupplierInfoCode = supplierInfo.Code;
                    goodsDeliveryDetails.DeliveryQuantity = details.QualityNumber;
                    goodsDeliveryDetails.CreatedUserId = CurrentUserInfo.UserId;
                    goodsDeliveryDetails.CreatedUserName = CurrentUserInfo.Name;
                    goodsDeliveryDetails.CreatedTime = DateTimeOffset.Now;
                    goodsDeliveryDetailsList.Add(goodsDeliveryDetails);
                }

                // 新增采购送货关系表
                var vsitem = new PurchaseOrderVsGoodsDelivery()
                {
                    PurchaseOrderId = purchaseOrderModel.Id,
                    GoodsDeliveryId = goodsDeliveryModel.Id
                };
                await _purchaseOrderVsGoodsDeliveryRep.InsertAsync(vsitem);

                //创建送货预约信息
                var appointmenModel = input.Adapt<GoodsDeliveryAppointment>();
                appointmenModel.TransportCompany = "N/A";
                appointmenModel.TransportVehicle = "N/A";
                appointmenModel.DriverName = "N/A";
                appointmenModel.DriverPhone = "N/A";
                appointmenModel.DriverQualification = "N/A";
                appointmenModel.ExpressInfoNo = "N/A";
                appointmenModel.CollectDeliveryUserName = "N/A";
                appointmenModel.CollectDeliveryUserPhone = "N/A";
                appointmenModel.DeliverGoodsPlaceShip = supplierInfo.ContactAddress;
                appointmenModel.CollectDeliveryPlaceShip = "上海市松江区文吉路555号";
                appointmenModel.DeliveryID = goodsDeliveryModel.Id;
                appointmenModel.DeliveryNo = goodsDeliveryModel.DeliveryNo;
                appointmenModel.Status = AuditStatusEnum.yuyuezhong; //预约中
                appointmenModel.DeliverDate = DateTimeOffset.Now; //发货日期
                appointmenModel.EstimatedDate = DateTimeOffset.Now; //预计到达日期
                await _goodsDeliveryAppointmentRep.InsertAsync(appointmenModel);

                //创建一条提交记录
                var supplierExaminerFlowerModel = new SupplierExamineFlower()
                {
                    Status = AuditStatusEnum.yuyuezhong, //预约中
                    DeliveryID = goodsDeliveryModel.Id,
                    Remarks = "预约中"
                };
                await _supplierExamineFlowerRep.InsertAsync(supplierExaminerFlowerModel);

                // 批量插入送货单明细
                await _goodsDeliveryDetailsRep.Context.BulkInsertAsync(goodsDeliveryDetailsList);
            }

            // 更新收货单明细供应商是否处理状态
            foreach (var item in input)
            {
                var collectDeliveryDetails = await _collectDeliveryDetailsRep.FirstOrDefaultAsync(z => z.Id == item.Id);
                collectDeliveryDetails.IsSupperHandle = YesOrNot.Y;
                await _collectDeliveryDetailsRep.UpdateAsync(collectDeliveryDetails);
            }
        }
    }
}
